package com.open.common.utils;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 加密工具类
 * 提供MD5和SHA-256加密功能
 */
public final class EncryptionUtil {

	// 常量定义
	private static final char[] HEX_DIGITS = {
			'0', '1', '2', '3', '4', '5', '6', '7',
			'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
	};
	private static final String DEFAULT_SALT = "5U8j3mZ7x!A%D*G-KaPdSgVkYp2s5v8y/B?E(H+MbQeThWmZq4t6w9z$C&F)J@NcRfUjXn2r5u8x/A?D*G-KaPdSgVkYp3s6v9y$B&E)H+MbQeThWmZq4t7w!z%C*F";
	private static final String MD5_ALGORITHM = "MD5";
	private static final String SHA256_ALGORITHM = "SHA-256";

	// 私有构造方法，防止实例化
	private EncryptionUtil() {
		throw new AssertionError("Cannot instantiate utility class");
	}

	/**
	 * MD5加密
	 */
	public static String encodeMD5(String input) {
		return hashWithAlgorithm(input, null, MD5_ALGORITHM);
	}

	/**
	 * SHA-256加密（使用默认盐值）
	 */
	public static String encode(String input) {
		return encode(input, DEFAULT_SALT);
	}

	/**
	 * SHA-256加密（使用指定盐值）
	 */
	public static String encode(String input, String salt) {
		return hashWithAlgorithm(input, salt, SHA256_ALGORITHM);
	}

	/**
	 * 通用的哈希计算方法
	 */
	private static String hashWithAlgorithm(String input, String salt, String algorithm) {
		String actualInput = getNonNullString(input);
		String actualSalt = getNonNullString(salt);

		try {
			MessageDigest digest = MessageDigest.getInstance(algorithm);
			String saltedInput = actualInput + actualSalt;
			byte[] hashBytes = digest.digest(saltedInput.getBytes(StandardCharsets.UTF_8));
			return toHex(hashBytes);
		} catch (NoSuchAlgorithmException e) {
			throw new RuntimeException(algorithm + " algorithm not available", e);
		} catch (Exception e) {
			throw new RuntimeException(algorithm + " encoding failed", e);
		}
	}

	/**
	 * 字节数组转十六进制字符串
	 */
	private static String toHex(byte[] bytes) {
		StringBuilder sb = new StringBuilder(bytes.length * 2);
		for (byte b : bytes) {
			sb.append(HEX_DIGITS[(b >>> 4) & 0x0F]);
			sb.append(HEX_DIGITS[b & 0x0F]);
		}
		return sb.toString();
	}

	/**
	 * 处理空字符串
	 */
	private static String getNonNullString(String str) {
		return str == null ? "" : str;
	}

	// 测试方法
	public static void main(String[] args) {
		System.out.println("SHA-256 encode : " + encode("dashu123"));
		//System.out.println("MD5 encode 'admin': " + encodeMD5("admin"));
	}
}